﻿using System.Configuration;
using Reactor.Environment;

namespace Reactor.Messaging.ServiceBus
{
    public class BusConfiguration
    {
        #region Fields

        private byte? _maxDeliveryAttempts;

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the connection data isntance to use.
        /// </summary>
        /// <value>The connection data.</value>
        public virtual PlatformConnectionData ConnectionData { get; set; }

        /// <summary>
        /// Gets or sets the message handler registry.
        /// </summary>
        /// <value>The message handler registry.</value>
        public virtual IHandlerRegistry MessageHandlerRegistry { get; set; }

        /// <summary>
        /// Gets or sets the destination registry.
        /// </summary>
        /// <value>The destination registry.</value>
        public virtual IDestinationRegistry DestinationRegistry { get; set; }

        /// <summary>
        /// Gets or sets the current endpoint input queue.
        /// </summary>
        /// <value>The current endpoint input queue.</value>
        public virtual PointToPointChannel CurrentEndpointInputChannel { get; set; }

        /// <summary>
        /// Gets or sets the dead letter queue all messages are to be sent when the maximum number of deliveries has been exceeded.
        /// </summary>
        /// <value>The dead letter queue.</value>
        public virtual PointToPointChannel DeadLetterChannel { get; set; }

        /// <summary>
        /// Gets or a value indicating whether or not to flush the primary input queue on startup. This value is attempted to be 
        /// obtained from application configuration first. If no value is present, a default value of <c>false</c> is assumed.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if the primary endpoint is to flush its primary input queue on startup; otherwise, <c>false</c>.
        /// </value>
        public bool FlushPrimaryInputQueueOnStartup
        {
            get
            {
                return DetermineBooleanValueFromConfiguration("FlushPrimaryInputQueueOnStartup", false);
            }
        }

        /// <summary>
        /// Gets a value indicating whether to terminate non-durable subscriptions on shutdown. 
        /// <remarks>A true value will prevent publishers from issuing messages to the broker when there are 
        /// no active listeners. Most brokers will not deliver such messages, but this eliminates the 
        /// unnecessary producer-to-broker traffic.</remarks>
        /// </summary>
        /// <value>
        /// 	<c>true</c> if the endpoint is to terminate non-durable subscriptions on shutdown; otherwise, 
        /// <c>false</c>. This value is obtained from application configuration. If it doesnt exist, a default 
        /// value of <c>true</c> is assumed.
        /// </value>
        public bool TerminateNonDurableSubscriptionsOnShutdown
        {
            get
            {
                return DetermineBooleanValueFromConfiguration("TerminateNonDurableSubscriptionsOnShutdown", true);
            }
        }

        /// <summary>
        /// Gets or sets the maximum number of times a message will be attempted delivery before being sent to the dead letter queue.
        /// </summary>
        /// <value>The max delivery attempts.</value>
        public virtual byte? MaxDeliveryAttempts
        {
            get
            {
                if (!_maxDeliveryAttempts.HasValue)
                    DiscoverMaxDeliveryAttempts();

                return _maxDeliveryAttempts;
            }
            set { _maxDeliveryAttempts = value; }
        }

        #endregion

        private void DiscoverMaxDeliveryAttempts()
        {
            var configSetting = ConfigurationManager.AppSettings["MaxDeliveryAttempts"];

            // ReSharper disable RedundantAssignment
            byte tmp = 3;
            byte.TryParse(configSetting, out tmp);
            // ReSharper restore RedundantAssignment

            _maxDeliveryAttempts = tmp;
        }

        private static bool DetermineBooleanValueFromConfiguration(string configKey, bool defaultValue)
        {
            var configSetting = ConfigurationManager.AppSettings[configKey];
            if (configSetting == null) return defaultValue;

            bool tmp;

            return (!bool.TryParse(configSetting, out tmp)) ? defaultValue : tmp;
        }
    }
}
